import 'dart:async';
import 'dart:ui';

import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flame_audio/flame_audio.dart';
import 'Tile.dart';
import 'GameWrapper.dart';
import 'main.dart';

class GameBoard extends PositionComponent with HasGameRef<MyGame> {
  static int gridSize = 8; // 8x8网格
  static const double tileSize = 50.0; // 每个方块的大小
  static const double spacing = 2.0; // 方块之间的间距
  static const double padding = 10.0; // 面板内边距

  late List<List<Tile?>> grid;
  bool audioInitialized = false; // 音频是否初始化成功
  Tile? selectedTile;
  late AudioPool? pool;
  bool isProcessing = false; // 添加处理状态标志
  late RectangleComponent background; // 添加背景组件

  @override
  Future<void> onLoad() async {
    super.onLoad();
    
    // 设置面板尺寸（包含内边距）
    size = Vector2.all((tileSize + spacing) * gridSize - spacing + padding * 2);
    
    // 计算游戏面板居中位置（考虑顶部UI区域和内边距）
    final topUIHeight = 0; // 顶部UI区域高度
    final horizontalPadding = 10.0; // 水平内边距
    final verticalPadding = 10.0; // 垂直内边距（顶部UI区域下方）
    
    // 可用游戏区域尺寸（减去内边距）
    final gameAreaWidth = gameRef.size.x - 2 * horizontalPadding;
    final gameAreaHeight = gameRef.size.y - topUIHeight - verticalPadding * 2;
    
    // 水平居中
    final centerX = horizontalPadding + (gameAreaWidth - size.x) / 2;
    
    // 垂直居中在可用游戏区域
    final centerY = topUIHeight + verticalPadding + (gameAreaHeight - size.y) / 2;
    
    position = Vector2(centerX, centerY);

    background = RectangleComponent(
      size: size,
      paint: Paint()..color = const Color(0x80FFFFFF), // 白色半透明背景
    );
    add(background);

    // 安全地初始化音频播放器
    _initAudio();

    initializeGrid();
  }

  // 初始化音频系统
  Future<void> _initAudio() async {
    try {
      await FlameAudio.audioCache.load('wow.mp3');
      pool = await FlameAudio.createPool('wow.mp3', maxPlayers: 3);

      audioInitialized = true;
      print('音频初始化成功');
    } catch (e) {
      audioInitialized = false;
      print('音频初始化失败: $e');
      print('没有音效');
    }
  }

  // 初始化游戏网格
  void initializeGrid() {
    grid = List.generate(gridSize, (_) => List.filled(gridSize, null));

    for (int row = 0; row < gridSize; row++) {
      for (int col = 0; col < gridSize; col++) {
        // 创建新方块，确保初始状态没有匹配
        TileType type;
        do {
          type = TileType.random();
        } while (hasMatchAt(row, col, type));

        final tile = Tile(
          type: type,
          position: Vector2(
            col * (tileSize + spacing) + padding, // 添加左边距
            row * (tileSize + spacing) + padding, // 添加上边距
          ),
          size: Vector2.all(tileSize),
          row: row,
          col: col,
        );

        grid[row][col] = tile;
        add(tile);
      }
    }
  }

  // 检查在指定位置放置某种类型的方块是否会形成匹配
  bool hasMatchAt(int row, int col, TileType type) {
    // 检查水平方向
    if (col >= 2 &&
        grid[row][col - 1]?.type == type &&
        grid[row][col - 2]?.type == type) {
      return true;
    }

    // 检查垂直方向
    if (row >= 2 &&
        grid[row - 1][col]?.type == type &&
        grid[row - 2][col]?.type == type) {
      return true;
    }

    return false;
  }

  // 处理方块点击
  void onTileSelected(Tile tile) {
    // 如果游戏暂停或正在处理中，忽略点击
    final gameWrapper = parent as GameWrapper;
    if (gameWrapper.isPaused() || isProcessing) return;

    if (selectedTile == null) {
      // 第一次选择
      selectedTile = tile;
      tile.isSelected = true;
    } else if (selectedTile == tile) {
      // 取消选择
      selectedTile!.isSelected = false;
      selectedTile = null;
    } else if (areAdjacent(selectedTile!, tile)) {
      // 尝试交换方块
      attemptSwap(selectedTile!, tile);
      selectedTile!.isSelected = false;
      selectedTile = null;
    } else {
      // 选择另一个方块
      selectedTile!.isSelected = false;
      selectedTile = tile;
      tile.isSelected = true;
    }
  }

  // 检查两个方块是否相邻
  bool areAdjacent(Tile a, Tile b) {
    return (a.row == b.row && (a.col - b.col).abs() == 1) ||
        (a.col == b.col && (a.row - b.row).abs() == 1);
  }

  // 尝试交换方块
  void attemptSwap(Tile a, Tile b) {
    isProcessing = true; // 开始处理

    // 保存原始位置
    final originalRowA = a.row;
    final originalColA = a.col;
    final originalRowB = b.row;
    final originalColB = b.col;

    // 交换网格中的位置和引用
    a.row = originalRowB;
    a.col = originalColB;
    b.row = originalRowA;
    b.col = originalColA;

    // 更新网格引用
    grid[originalRowA][originalColA] = b;
    grid[originalRowB][originalColB] = a;

    // 添加动画让方块移动到新位置（考虑内边距）
    a.add(
      MoveToEffect(
        Vector2(
          a.col * (tileSize + spacing) + padding, // 添加左边距
          a.row * (tileSize + spacing) + padding, // 添加上边距
        ),
        EffectController(duration: 0.3),
      ),
    );

    b.add(
      MoveToEffect(
        Vector2(
          b.col * (tileSize + spacing) + padding, // 添加左边距
          b.row * (tileSize + spacing) + padding, // 添加上边距
        ),
        EffectController(duration: 0.3),
      ),
    );

    // 延迟检查是否形成匹配，等待交换动画完成
    Future.delayed(const Duration(milliseconds: 400), () {
      final matches = findMatches();
      if (matches.isEmpty) {
        // 如果没有匹配，交换回来
        a.row = originalRowA;
        a.col = originalColA;
        b.row = originalRowB;
        b.col = originalColB;

        grid[originalRowA][originalColA] = a;
        grid[originalRowB][originalColB] = b;

        // 添加动画让方块移回原位
        // 先移除之前的移动效果
        a.children.whereType<MoveToEffect>().forEach((effect) => effect.removeFromParent());
        b.children.whereType<MoveToEffect>().forEach((effect) => effect.removeFromParent());

        // 添加回退动画
        a.add(
          MoveToEffect(
            Vector2(
              originalColA * (tileSize + spacing) + padding, // 添加左边距
              originalRowA * (tileSize + spacing) + padding, // 添加上边距
            ),
            EffectController(duration: 0.3),
          ),
        );

        b.add(
          MoveToEffect(
            Vector2(
              originalColB * (tileSize + spacing) + padding, // 添加左边距
              originalRowB * (tileSize + spacing) + padding, // 添加上边距
            ),
            EffectController(duration: 0.3),
          ),
        );

        isProcessing = false; // 处理结束
      } else {
        // 有匹配，消除方块并填充新方块
        removeMatches(matches);
      }
    });
  }

  // 查找所有匹配
  List<List<Tile>> findMatches() {
    final matches = <List<Tile>>[];

    // 检查水平匹配
    for (int row = 0; row < gridSize; row++) {
      for (int col = 0; col < gridSize - 2; col++) {
        final tile = grid[row][col];
        if (tile != null &&
            tile.type == grid[row][col + 1]?.type &&
            tile.type == grid[row][col + 2]?.type) {

          // 找到匹配的起始点，检查更长的匹配
          int matchLength = 3;
          while (col + matchLength < gridSize &&
              grid[row][col + matchLength]?.type == tile.type) {
            matchLength++;
          }

          // 添加匹配的方块
          final match = <Tile>[];
          for (int i = 0; i < matchLength; i++) {
            match.add(grid[row][col + i]!);
          }
          matches.add(match);

          // 跳过已匹配的方块
          col += matchLength - 1;
        }
      }
    }

    // 检查垂直匹配
    for (int col = 0; col < gridSize; col++) {
      for (int row = 0; row < gridSize - 2; row++) {
        final tile = grid[row][col];
        if (tile != null &&
            tile.type == grid[row + 1][col]?.type &&
            tile.type == grid[row + 2][col]?.type) {

          // 找到匹配的起始点，检查更长的匹配
          int matchLength = 3;
          while (row + matchLength < gridSize &&
              grid[row + matchLength][col]?.type == tile.type) {
            matchLength++;
          }

          // 添加匹配的方块
          final match = <Tile>[];
          for (int i = 0; i < matchLength; i++) {
            match.add(grid[row + i][col]!);
          }
          matches.add(match);

          // 跳过已匹配的方块
          row += matchLength - 1;
        }
      }
    }

    return matches;
  }

  // 消除匹配的方块
  void removeMatches(List<List<Tile>> matches) async {
    final Set<Tile> tilesToRemove = <Tile>{};

    // 收集所有需要消除的方块
    for (final match in matches) {
      for (final tile in match) {
        tilesToRemove.add(tile);
      }
    }

    // 播放音效（如果音频播放器已初始化）
    if (audioInitialized) {
      try {
        final stop = await pool?.start(volume: 0.8);
      } catch (e) {
        print('播放音效时出错: $e');
      }
    }

    // 移除方块
    for (final tile in tilesToRemove) {
      tile.removeFromParent();
      grid[tile.row][tile.col] = null;
      
      // 通知GameWrapper增加得分
      final gameWrapper = parent as GameWrapper;
      gameWrapper.addScore(10); // 每个方块10分
    }

    // 填充空位
    await fillEmptySpaces(); // 使用await等待填充完成

    // 检查是否还有连锁反应
    final newMatches = findMatches();
    if (newMatches.isNotEmpty) {
      removeMatches(newMatches);
    } else {
      isProcessing = false; // 所有处理结束
    }
  }

  Future<void> fillEmptySpaces() async {
    final completers = <Completer<void>>[];

    // 首先，让已有的方块下落
    for (int col = 0; col < gridSize; col++) {
      // 从底部向上计算每一块需要下落的距离
      int emptySpacesBelow = 0;
      for (int row = gridSize - 1; row >= 0; row--) {
        if (grid[row][col] == null) {
          // 发现一个空位
          emptySpacesBelow++;
        } else {
          // 发现一个方块，让它下落emptySpacesBelow格
          if (emptySpacesBelow > 0) {
            final tile = grid[row][col]!;
            final newRow = row + emptySpacesBelow;

            // 更新网格数据结构
            grid[newRow][col] = tile;
            grid[row][col] = null;
            tile.row = newRow;

            // 创建Completer来跟踪动画完成
            final completer = Completer<void>();
            completers.add(completer);

            // 添加下落动画（考虑内边距）
            tile.add(
              MoveToEffect(
                Vector2(
                  col * (tileSize + spacing) + padding, // 添加左边距
                  newRow * (tileSize + spacing) + padding, // 添加上边距
                ),
                EffectController(duration: 0.3),
              )..onComplete = () {
                completer.complete();
              },
            );
          }
        }
      }
    }

    // 然后，在顶部生成新方块
    for (int col = 0; col < gridSize; col++) {
      // 计算该列有多少个空位需要填充
      int emptySpaces = 0;
      for (int row = 0; row < gridSize; row++) {
        if (grid[row][col] == null) {
          emptySpaces++;
        }
      }

      // 在顶部生成新方块填补空位（考虑内边距）
      for (int i = 0; i < emptySpaces; i++) {
        final TileType type = TileType.random();
        // 新方块应该在网格的第i行（从0开始）
        final int newRow = i;
        // 新方块的初始位置应该在网格顶部之外，第(-emptySpaces+i)行
        final newTile = Tile(
          type: type,
          position: Vector2(
            col * (tileSize + spacing) + padding, // 添加左边距
            (-emptySpaces + i) * (tileSize + spacing) + padding, // 添加上边距
          ),
          size: Vector2.all(tileSize),
          row: newRow,
          col: col,
        );

        grid[newRow][col] = newTile;
        add(newTile);

        // 创建Completer来跟踪动画完成
        final completer = Completer<void>();
        completers.add(completer);

        newTile.add(
          MoveToEffect(
            Vector2(
              col * (tileSize + spacing) + padding, // 添加左边距
              newRow * (tileSize + spacing) + padding, // 添加上边距
            ),
            EffectController(duration: 0.3),
          )..onComplete = () {
            completer.complete();
          },
        );
      }
    }

    // 等待所有动画完成
    if (completers.isNotEmpty) {
      await Future.wait(completers.map((c) => c.future));
    }
  }
}